// file:libc/ansi/string.c
// autor:jiang xinpeng
// time:2021.8.12
// update: 2024.3.14
// copyright:(C) 2020-2050 by jiang xinpeng,All right are reserved.

#include <string.h>
#include <ctype.h>
#include <types.h>
#include <stddef.h>
#include <stdio.h>

int strcmp(const char *src, const char *targe)
{
    char *s = (char *)src, *t = (char *)targe;

    if (!s || !t)
        return -1;

    // cmp two string while any string current char no equal '\0'
    for(;*s==*t;s++,t++)
    {
        if(!*s)
            break;
    }
    return (*s - *t); // >0 uper  =0 equal  <0 lower
}

char *strcat(char *targe, const char *src)
{
    int i, j;
    char *temp = targe;

    // go to targe string end
    while (*targe != '\0')
    {
        targe++;
    }
    // copy src to targe end
    while (*src != '\0')
    {
        *targe++ = *src++;
    }
    *targe = '\0'; // write string eof flags
    return temp;
}

char *strstr(const char *targe, const char *src)
{
    int i=0, j=0; // I control src pos,j control targe

    while (*(src + i) != '\0' && *(targe + j) != '\0')
    {
        // equal next char
        if (*(src + i) == *(targe + i))
        {
            i++;
            j++;
        }
        // if other char no equal
        else
        {
            i = i - j + 1; // src back to times current cmp start char+1
            j = 0;         // from sub string start char restart cmp
        }
    }
    // if is targe str has full cmp finish
    if (*(targe + j) == '\0')
        return (char *)(src + (i - j));
}

char *strcpy(char *targe, const char *src)
{
    char *str = targe;

    while (*src != '\0')
    {
        *targe++ = *src++;
    }
    *targe = '\0';
    return str;
}

char *strchr(const char *targe, char src)
{
    char *s = (char *)targe;

    while (*s != '\0')
    {
        if (*s == src)
            return s;
        s++;
    }
    return NULL;
}

char *strrchr(const char *str, char c)
{
    char *ret;
    while (*str)
    {
        if (*str == c)
            ret = (char *)str;
        str++;
    }
    if (c == *str)
        ret = (char *)str;
    return ret;
}

int strpos(const char *str, char ch)
{
    int i = 0;
    int flags = 0;

    while (*str)
    {
        if (*str == ch)
        {
            flags = 1;
            break;
        }
        i++;
        str++;
    }
    if (flags)
        return i;
    else
        return -1;
}

int strlen(const char *str)
{
    uint32_t len = 0;
    char *s = (char *)str;

    while (*s++ != '\0')
    {
        ++len;
    }
    return len;
}

void *memset(void *src, uint8_t value, uint32_t size)
{
    uint8_t *buff = src;
    int i = 0;

    while (i < size)
    {
        *(buff + i) = value;
        i++;
    }

    return src;
}

void *memcpy(void *targe, const void *src, uint32_t size)
{
    uint8_t *_targe = targe, *_src = (char *)src;

    while (size-- > 0)
    {
        *_targe++ = *_src++;
    }
    return _targe;
}

void* memmove(void* dst,const void* src,uint32_t count)
{
    char* tmpdst = (char*)dst;
    char* tmpsrc = (char*)src;

    if (tmpdst <= tmpsrc || tmpdst >= tmpsrc + count)
    {
        while(count--)
        {
            *tmpdst++ = *tmpsrc++; 
        }
    }
    else
    {
        tmpdst = tmpdst + count - 1;
        tmpsrc = tmpsrc + count - 1;
        while(count--)
        {
            *tmpdst-- = *tmpsrc--;
        }
    }

    return dst; 
}


int memcmp(const void *src, const void *targe, uint32_t len)
{
    int i;
    const uint8_t *src_t = src, *targe_t = targe;

    // len check
    for (i = 0; i < len; i++, targe_t++, src_t++)
    {
            if (*src_t - *targe_t > 0)
                return 1;
            else
            {
                if (*src_t - *targe_t < 0)
                    return -1;
            }
    }
    return 0;
}

char *strncat(char *dst, const char *src, int n)
{
    char *ret = dst;

    while (*dst != '\0')
        dst++;

    while (n && *dst != '\0' && *src != '\0')
    {
        *dst++ = *src++;
        n--;
    }
}

char *strncpy(char *_dst, const char *_src, int n)
{
    char *s = (char *)_src;
    char *r = _dst;

    while (n > 0&&*s)
    {
        *r++ = *s++;
        n--;
    }
    *r='\0';
}

int strncmp(const char *s1, const char *s2, int n)
{
    if (!n)
        return 0;

    while (n-- && *s1 && (*s1 == *s2))
    {
        s1++;
        s2++;
    }
    if (n > 0)
        return (int)(*s1 - *s2);
    else
        return 0;
}

int strcoll(const char *str1, const char *str2)
{
    return strcmp(str1, str2);
}

size_t strspn(const char *s, const char *accept)
{
    const char *p;
    const char *a;
    size_t count;

    for (p = s; *p != '\0'; p++)
    {
        for (a = accept; *a != '\0'; a++)
        {
            if (*p == *a)
                break;
        }
        if (*a == '\0')
            return count;
        ++count;
    }
    return count;
}

const char *strpbrk(const char *str1, const char *str2)
{
    const char *temp1 = str1;
    const char *temp2 = str2;

    if (!str1 || !str2)
        return NULL;

    while (*temp1 != '\0')
    {
        temp2 = str2;
        while (*temp2)
        {
            if (*temp2 == *temp1)
                return temp1;
            else
                temp2++;
        }
        temp1++;
    }
    return NULL;
}
